package com.lzy.controller;

import com.lzy.config.MinIOConfig;
import com.lzy.exceptions.GraceException;
import com.lzy.pojo.vo.VideoMsgVO;
import com.lzy.utils.JcodecVideoUtil;
import com.lzy.utils.MinIOUtils;
import com.lzy.api.feign.UserInfoMicroServiceFeign;
import com.lzy.grace.result.GraceJSONResult;
import com.lzy.grace.result.ResponseStatusEnum;
import com.lzy.pojo.vo.UsersVO;
import com.lzy.utils.JsonUtils;
import com.lzy.utils.QrCodeUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@RestController
@RequestMapping("file")
public class FileController {

    @Autowired
    MinIOConfig minIOConfig;

    @Autowired
    private UserInfoMicroServiceFeign userInfoMicroServiceFeign; //调用main-service服务中的服务
    @PostMapping("uploadFace1")
    public Object hello(@RequestParam("file") MultipartFile file,
                        String userId,
                        HttpServletRequest request) throws IOException {

        String filename = file.getOriginalFilename(); // 获得文件原始名称
        String suffixName = filename.substring(filename.lastIndexOf(".")); // 从最后一个点开始截取，获取文件类型
        String newFileName = userId + suffixName; // 文件新名称

        // 设置文件存储路径，可以存放在任意路径
        String rootPath = "D:" + File.separator + "Code" + File.separator + "temp" + File.separator; // 上传文件存放位置
        String filePath = rootPath + File.separator + "face" + File.separator + newFileName;
        File newFile = new File(filePath);
        // 判断目标文件所在目录是否存在
        if(!newFile.getParentFile().exists()){
            // 如果目标文件所在目录不存在，则创建父级目录
            newFile.getParentFile().mkdirs();
        }
        // 将内存中的数据写入磁盘-本地d盘
        file.transferTo(newFile);

        return GraceJSONResult.ok();
    }

    @PostMapping("uploadFace")
    public Object uploadFace(@RequestParam("file") MultipartFile file,
                        String userId,
                        HttpServletRequest request) throws Exception {

        if(StringUtils.isBlank(userId)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename(); // 获得文件原始名称
        if(StringUtils.isBlank(filename)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        filename = "face" + "/" + userId + "/" + filename;
        MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                filename,file.getInputStream());

        String faceUrl = minIOConfig.getFileHost() + "/" + minIOConfig.getBucketName() + "/" + filename;

        /**
         *  微服务远程调用更新用户头像到数据库 OpenFeign
         *  如果前端没有保存按钮则可以做，如果有保存按钮，则在前端进行触发
         *  此处则不需要进行微服务调用，让前端触发保存调用后台进行保存
         */
        GraceJSONResult jsonResult = userInfoMicroServiceFeign.updateFace(userId,faceUrl);
        Object data = jsonResult.getData();
        String json = JsonUtils.objectToJson(data);
        UsersVO usersVO = JsonUtils.jsonToPojo(json, UsersVO.class);
        return GraceJSONResult.ok(usersVO);
    }


    /**
     * 生成微信二维码
     */
    @PostMapping("generateorQrCode")
    public GraceJSONResult generateorQrCode(String wechatNumber,
                                   String userId) throws Exception {

        // 生成二维码数据
        Map<String,String> map = new HashMap<>();
        map.put("wechatNumber",wechatNumber);
        map.put("userId",userId);

        // 把对象转换为json字符串，用于存储到二维码中
        String qrCodeUrl = QrCodeUtils.generateQRCode(JsonUtils.objectToJson(map));

        // 将二维码保存到MinIO
        if(StringUtils.isNotBlank(qrCodeUrl)){
            String uuid = UUID.randomUUID().toString();
            String objectname = "wechatNumber" + "/" + userId + "/" + uuid + ".png";
            //从本地获取文件上传到minio，并将minio的地址返回给前端
            String imageQrCodeUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),objectname,qrCodeUrl,true);
            return GraceJSONResult.ok(imageQrCodeUrl);
        }
        return null;
    }
    @PostMapping("uploadFriendCircleBg")
    public Object uploadFriendCircleBg(@RequestParam("file") MultipartFile file,
                             String userId) throws Exception {

        if(StringUtils.isBlank(userId)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename(); // 获得文件原始名称
        if(StringUtils.isBlank(filename)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        filename = "FriendCircleBg" + "/" + userId + "/" + dealWithOutFilename(filename); //minio中文件路径及名称
        //获取minio中的映射路径
        String imageUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                filename,file.getInputStream(),true);

        /**
         *  微服务远程调用更新用户背景到数据库 OpenFeign
         *  如果前端没有保存按钮则可以做，如果有保存按钮，则在前端进行触发
         *  此处则不需要进行微服务调用，让前端触发保存调用后台进行保存
         */
        GraceJSONResult jsonResult = userInfoMicroServiceFeign
                                        .updateFriendCircleBg(userId,imageUrl);
        Object data = jsonResult.getData();
        String json = JsonUtils.objectToJson(data);
        UsersVO usersVO = JsonUtils.jsonToPojo(json, UsersVO.class);
        return GraceJSONResult.ok(usersVO);
    }

    @PostMapping("uploadChatBg")
    public Object uploadChatBg(@RequestParam("file") MultipartFile file,
                                       String userId) throws Exception {

        if(StringUtils.isBlank(userId)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename(); // 获得文件原始名称
        if(StringUtils.isBlank(filename)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        filename = "uploadChatBg" + "/" + userId + "/" + dealWithOutFilename(filename); //minio中文件路径及名称
        //获取minio中的映射路径
        String imageUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                filename,file.getInputStream(),true);

        /**
         *  微服务远程调用更新用户背景到数据库 OpenFeign
         *  如果前端没有保存按钮则可以做，如果有保存按钮，则在前端进行触发
         *  此处则不需要进行微服务调用，让前端触发保存调用后台进行保存
         */
        GraceJSONResult jsonResult = userInfoMicroServiceFeign
                .uploadChatBg(userId,imageUrl);
        Object data = jsonResult.getData();
        String json = JsonUtils.objectToJson(data);
        UsersVO usersVO = JsonUtils.jsonToPojo(json, UsersVO.class);
        return GraceJSONResult.ok(usersVO);
    }



    @PostMapping("uploadFriendCircleImage")
    public Object uploadFriendCircleImage(@RequestParam("file") MultipartFile file,
                               String userId) throws Exception {

        if(StringUtils.isBlank(userId)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename(); // 获得文件原始名称
        if(StringUtils.isBlank(filename)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        filename = "FriendCircleImage" + "/" + userId + "/" + dealWithOutFilename(filename); //minio中文件路径及名称
        //获取minio中的映射路径
        String imageUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                filename,file.getInputStream(),true);

        return GraceJSONResult.ok(imageUrl);
    }

    @PostMapping("uploadChatPhoto")
    public Object uploadChatPhoto(@RequestParam("file") MultipartFile file,
                                          String userId) throws Exception {
        //获取minio中的映射路径
        String imageUrl = upLoadFiles(file,userId,"image");
        return GraceJSONResult.ok(imageUrl);
    }

    @PostMapping("uploadChatVideo")
    public Object uploadChatVideo(@RequestParam("file") MultipartFile file,
                                  String userId) throws Exception {

        //获取minio中的映射路径
        String vedioUrl = upLoadFiles(file,userId,"video");

        // 封面获取 -- 视频截帧，获取第一帧
        String coverName = UUID.randomUUID().toString() + ".jpg"; // 视频封面的名称
        String coverPath = JcodecVideoUtil.videoFramesPath
                + File.separator + "vedio"
                + File.separator + coverName;
        File coverFile = new File(coverPath);

        if(!coverFile.getParentFile().exists()){
            coverFile.getParentFile().mkdirs();
        }

        JcodecVideoUtil.fetchFrame(file, coverFile);

        // 上传封面到minio
        String minioCoverPath = "chat" + "/" + userId + "/" + "video" + "/"  + "cover"
                + "/" + coverName; //minio中文件路径及名称
        //获取minio中的映射路径
        String coverUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                                                minioCoverPath,
                                                new FileInputStream(coverFile),
                                        true);

        // 包装类，返回视频url和封面url
        VideoMsgVO videoMsgVO = new VideoMsgVO();
        videoMsgVO.setVideoPath(vedioUrl);
        videoMsgVO.setCover(coverUrl);

        return GraceJSONResult.ok(videoMsgVO);
    }

    @PostMapping("uploadChatVoice")
    public Object uploadChatVoice(@RequestParam("file") MultipartFile file,
                                  String userId) throws Exception {

        String vedioUrl = upLoadFiles(file,userId,"voice");
        return GraceJSONResult.ok(vedioUrl);
    }

    private String upLoadFiles(MultipartFile file,String userId,String type) throws Exception {

        if(StringUtils.isBlank(userId)){
            GraceException.display(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        String filename = file.getOriginalFilename(); // 获得文件原始名称
        if(StringUtils.isBlank(filename)){
            GraceException.display(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        filename = "chat" + "/" + userId + "/" + type + "/" + dealWithOutFilename(filename); //minio中文件路径及名称
        //获取minio中的映射路径
        String fileUrl = MinIOUtils.uploadFile(minIOConfig.getBucketName(),
                filename,file.getInputStream(),true);

        return fileUrl;
    }
    private String dealWithFilename(String filename){
        String suffixName = filename.substring(filename.lastIndexOf(".")); // 从最后一个点开始截取，获取文件类型
        String FName = filename.substring(0,filename.lastIndexOf(".")); // 获取文件名
        String uuid = UUID.randomUUID().toString();
        return FName + "-" + uuid + suffixName;
    }

    private String dealWithOutFilename(String filename){
        String suffixName = filename.substring(filename.lastIndexOf(".")); // 从最后一个点开始截取，获取文件类型
        String uuid = UUID.randomUUID().toString();
        return uuid + suffixName;
    }
}
